#include "camera.h"

camera::camera(QObject *parent) :
    QObject(parent)
{
    m_ServerConnected = false;///???
    n_ServerConnected = false;

    this->tcp_socket_short = new QTcpSocket(this);
    connect(this->tcp_socket_short,SIGNAL(readyRead()),this,SLOT(socket_short_rec()));
    connect(tcp_socket_short, SIGNAL(connected()), this, SLOT(socket_short_connected()));
    connect(tcp_socket_short, SIGNAL(disconnected()), this, SLOT(socket_short_desconnected()));
    connect(tcp_socket_short, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayshortError(QAbstractSocket::SocketError)));

    //car number link
    this->tcp_socket_long = new QTcpSocket(this);
    connect(tcp_socket_long,SIGNAL(readyRead()),this,SLOT(socket_long_rec()));
    connect(tcp_socket_long, SIGNAL(connected()), this, SLOT(socket_long_connected()));
    connect(tcp_socket_long, SIGNAL(disconnected()), this, SLOT(socket_long_desconnected()));
    connect(tcp_socket_long, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));

    link_Timer = new QTimer();
    connect(link_Timer,SIGNAL(timeout()),SLOT(linkTimerOver())); ///先关闭长链接
    connect(link_Timer,SIGNAL(timeout()),SLOT(socket_long_send()));///然后送发请求车牌识别信息包头/////???
   // this->link_Timer->start(LINK_TIME);

    timer_receive=new QTimer();
    connect(timer_receive,SIGNAL(timeout()),SLOT(CameraRecive()));
}
void camera::linkTimerOver()
{
    this->socket_link(this->camerarIp);
}
void camera::socket_link(QString ip)
{
    //short link
    this->camerarIp = ip;
    qDebug()<<"camera::socket_link"<<m_ServerConnected;
    if(m_ServerConnected)
    {
        return;
    }
    if(tcp_socket_long->state()== QAbstractSocket::ConnectedState)
    {
        tcp_socket_long->abort();
        tcp_socket_long->close();
        tcp_socket_long->disconnectFromHost();
        this->packHeader_long.clear();
    }
    tcp_socket_long->connectToHost(this->camerarIp,8200);
}

void camera::socket_long_send()///当客户端需要请求车牌识别结果时，需要向IPC设备8200端口号发起连接，并发送u32Size为32，u32Type为 0x1007的数据包。
{
    qDebug()<<"camera::socket_long_send()="<<this->camerarIp<<m_ServerConnected;
    if(!m_ServerConnected)
    {
        return;
    }
    pack_head_t pack;
    memset(pack.buffer,0,sizeof(pack));
    pack.data.u32Size = 32;
    pack.data.u32Type = 0x1007;
    this->packHeader_long.clear();
    this->picBuffer_long.clear();
    this->tcp_socket_long->write(pack.buffer,sizeof(pack));
}

void camera::longsocket_in(QString ip)
{
    //qDebug()<<this->camerarIp<<tcp_socket_long->state();
    if(tcp_socket_long->state()== QAbstractSocket::ConnectedState)
    {
        //qDebug()<<this->camerarIp<<"duan";
        tcp_socket_long->abort();
        tcp_socket_long->close();
        tcp_socket_long->disconnectFromHost();
        this->packHeader_long.clear();
    }
    this->camerarIp = ip;
    tcp_socket_long->connectToHost(this->camerarIp,8200);

    //qDebug()<<this->camerarIp<<"lian";
}

void camera::socket_short_request(int request)
{
    this->request_type = request;
    if(tcp_socket_short->state()== QAbstractSocket::ConnectedState)
    {
        tcp_socket_short->abort();
        tcp_socket_short->close();
        tcp_socket_short->disconnectFromHost();
    }
    this->tcp_socket_short->connectToHost(this->camerarIp,8117);
}

void camera::socket_short_request_open(int request)
{
    pack_head_t pack;
    memset(pack.buffer,0,sizeof(pack));
    pack.data.u32Size = 32;
    pack.data.u32Type = request;
    if(pack.data.u32Type == REQUEST_RS485)
    {
        pack.data.u32Size += this->picBuffer_short.length();
    }
    this->packHeader_short.clear();
    packHeader_short.append(pack.buffer,sizeof(pack));
    packHeader_short.append(this->picBuffer_short);

    if((this->short_fd=socket(AF_INET,SOCK_STREAM,0))<0)
    {
        qDebug()<<"creat short_fd error";
    }
    this->sd_addr.sin_family=AF_INET;
    this->sd_addr.sin_port=htons(8117);
    this->sd_addr.sin_addr.s_addr=inet_addr(this->camerarIp.toLocal8Bit().data());
    int s_len=sizeof(sd_addr);
    if(::connect(this->short_fd,(struct sockaddr*)&sd_addr,s_len)<0)
    {
        qDebug()<<"connect error";
        return ;
    }
    int n=::send(short_fd,packHeader_short.data(),packHeader_short.length(),0);
    usleep(180000);
    ::closesocket(this->short_fd);
    this->packHeader_short.clear();
    this->picBuffer_short.clear();
}

void camera::socket_short_send(QByteArray buf)///给摄像机发送 语音 屏幕信息 会封摄像机头部信息
{
    qDebug()<<"socket_short_send(QByteArray buf)";
    pack_head_t pack;
    QByteArray sendArray;
    ///***************************************
    //     添加摄像机数据包包头
    //***************************************
    memset(pack.buffer,0,sizeof(pack));
    pack.data.u32Size = 32;
    pack.data.u32Type = REQUEST_RS485;
    pack.data.u32Size += buf.length();
    sendArray.append(pack.buffer,sizeof(pack));
    sendArray.append(buf);
    if((this->short_fd=socket(AF_INET,SOCK_STREAM,0))<0)
           qDebug()<<"creat short_fd error";
    this->sd_addr.sin_family=AF_INET;
    this->sd_addr.sin_port=htons(8117);
    this->sd_addr.sin_addr.s_addr=inet_addr(this->camerarIp.toLocal8Bit().data());
    int s_len=sizeof(sd_addr);
    if(::connect(this->short_fd,(struct sockaddr*)&sd_addr,s_len)<0)
    {
        qDebug()<<"connect error";
        return ;
    }
    int n=::send(short_fd,sendArray.data(),sendArray.length(),0);
    usleep(180000);
    ::closesocket(this->short_fd);
}

void camera::socket_short_connected() ///连接上回调函数
{
    n_ServerConnected = true;
    pack_head_t pack;
    memset(pack.buffer,0,sizeof(pack));
    pack.data.u32Size = 32;
    pack.data.u32Type = this->request_type;
    if(pack.data.u32Type == REQUEST_RS485)
    {
        pack.data.u32Size += this->picBuffer_short.length();
    }
    this->packHeader_short.clear();
    packHeader_short.append(pack.buffer,sizeof(pack));
    packHeader_short.append(this->picBuffer_short);
    tcp_socket_short->write(this->packHeader_short);
    this->packHeader_short.clear();
    this->picBuffer_short.clear();
    usleep(180000);
   // tcp_socket_short->waitForReadyRead(180000);
   // tcp_socket_short->disconnect();
   // tcp_socket_short->abort();
    qDebug() << "send request:" << this->request_type;
}
void camera::socket_short_desconnected()
{
    n_ServerConnected = false;
    pack_head_t pack;
    tcp_socket_short->close();
    memcpy(pack.buffer,this->packHeader_short.data(),sizeof(pack));
    // qDebug() << "short pack len:" <<  pack.data.u32Size;
    // qDebug() << "short pack type:" << hex << pack.data.u32Type;
    if(pack.data.u32Type == REQUEST_PHOTO_RES)
    {
        QPixmap aa;
        aa.loadFromData(this->picBuffer_short,0,Qt::AutoColor);
        emit carNumberRecEnd("",&aa);
    }
    this->packHeader_short.clear();
    this->picBuffer_short.clear();
}
void camera::socket_short_rec()
{
    if(this->packHeader_short.length() == 0)
    {
        this->packHeader_short = this->tcp_socket_short->read(32);
        this->picBuffer_short.clear();
    }
    this->picBuffer_short.append(tcp_socket_short->readAll());
    //qDebug() <<"packHeader_short:" << this->picBuffer_short.length();
}

void camera::socket_short_syncTime()
{
    QByteArray sendBuffer;
    yb_led_syncTime(&sendBuffer);
    this->socket_short_send(sendBuffer);
    //    this->picBuffer_short.clear();
    //    this->picBuffer_short.append(sendBuffer);
    //    this->socket_short_request(REQUEST_RS485);
    qDebug()<<"synctime";
}

//void camera::socket_short_display(char addr,QByteArray info)
//{
//        QByteArray sendArray;
//        sendArray.append(0xAA);
//        sendArray.append(0x55);
//        sendArray.append(0xAA);
//        sendArray.append(0x66);
//        sendArray.append(addr);
//        sendArray.append((char)(info.length()));
//        sendArray.append(info);
//        char check = (char)(info.length());
//        foreach(char byte,info)
//        {
//            check ^= byte;
//        }
//        sendArray.append(check);
//        this->picBuffer_short.clear();
//        this->picBuffer_short.append(sendArray);
//        this->socket_short_request(REQUEST_RS485);
//}


void camera::socket_short_display(displayData_t *info) ///次函数会封装 语音  屏幕的头部信息 然后通过socket_short_send添加摄像机头部信息发给摄像机，摄像机转发，语音，屏幕
{
    qDebug()<<"socket_short_display"<<info->audioStr;
    QByteArray sendArray;
    //发送语音
    QTextCodec * gb2312 = QTextCodec::codecForName("GB2312");
    QByteArray temp=gb2312->fromUnicode(info->audioStr);
    sendArray.append(0xAA);
    sendArray.append(0x55);
    sendArray.append(0xAA);
    sendArray.append(0x66);
    if(info->audioStr == "车牌识别  一车一杆  减速慢行")
    {
        sendArray.append(0x01);
    }
    else
    {
        sendArray.append(0x02);
    }
    sendArray.append((char)(temp.length()));
    sendArray.append(temp);
    char check = (char)(temp.length());
    foreach(char byte,temp)
    {
        check ^= byte;
    }
    sendArray.append(check);
    this->socket_short_send(sendArray);

//    this->picBuffer_short.clear();
//    this->picBuffer_short.append(sendArray);
//    this->socket_short_request(REQUEST_RS485);
    //qDebug()<<"socket_short_display---voice";
    //发送显示屏
    for(int i=1;i<=4;i++)
    {
        if(!info->DispelayStr[i-1].isEmpty())
        {
            sendArray.clear();
            yb_led_create_park(i,BX_5K1,info->DispelayStr[i-1],&sendArray);
            this->socket_short_send(sendArray);

//            this->picBuffer_short.clear();
//            this->picBuffer_short.append(sendArray);
//            this->socket_short_request(REQUEST_RS485);
        }
    }
    qDebug()<<"socket_short_display---video";
}

void camera::socket_long_connected()///当客户端需要请求车牌识别结果时，需要向IPC设备8200端口号发起连接，并发送u32Size为32，u32Type为 0x1007的数据包。
{
    m_ServerConnected = true;
    pack_head_t pack;
    memset(pack.buffer,0,sizeof(pack));
    pack.data.u32Size = 32;
    pack.data.u32Type = 0x1007;
    this->packHeader_long.clear();
    this->picBuffer_long.clear();
    this->tcp_socket_long->write(pack.buffer,sizeof(pack));
    emit CameraLongConnect();
    qDebug() << "socket long connected";
}

void camera::socket_long_desconnected()
{
    m_ServerConnected = false;
    this->tcp_socket_long->close();
    qDebug() << "socket long desconnected!";
}

void camera::displayError(QAbstractSocket::SocketError)
{
    m_ServerConnected = false;
    //qDebug()<<this->camerarIp<<"error123:"<<this->tcp_socket_long->errorString();
}

void camera::displayshortError(QAbstractSocket::SocketError)
{
    n_ServerConnected = false;
    //qDebug()<<this->camerarIp<<"error123:"<<this->tcp_socket_short->errorString();
}

void camera::socket_long_rec()
{
    curentTime= QDateTime::currentDateTime();
    timer_receive->start(30000);
    pack_head_t *pack;
    this->link_Timer->stop();
    this->link_Timer->start(LINK_TIME);
    if(this->packHeader_long.length()==0)
    {
        this->packHeader_long = this->tcp_socket_long->read(32);
        pack = (pack_head_t *)this->packHeader_long.data();
        //qDebug() << "long rec len:" << this->packHeader_long.length();
        //qDebug() << "long size is:" << pack->data.u32Size;
        //qDebug() << "long type is:" << hex <<pack->data.u32Type;
        if(pack->data.u32Type != REQUEST_NUMBER_RES)                         ////ICE_EVENT_TYPE_VLPR_EVENT = 0x2002	车牌数据上报
        {
            this->packHeader_long.clear();
        }
        this->picBuffer_long.clear();
    }
    this->picBuffer_long.append(this->tcp_socket_long->readAll());
    pack = (pack_head_t *) this->packHeader_long.data();
    if(this->picBuffer_long.length() == (int)(pack->data.u32Size - 32))
    {
        ICE_VDC_PICTRUE_INFO_BUFFER_S *picBuffer = (ICE_VDC_PICTRUE_INFO_BUFFER_S *)this->picBuffer_long.data();
        //qDebug() << "car number:" << picBuffer->stPlateInfo.as8PlateNum;
        // qDebug() << "pic size:" << picBuffer->s32PicDataLen;
        QByteArray buffer;
        buffer.clear();
        buffer.append(picBuffer->as8PictureData,picBuffer->s32PicDataLen);
        QPixmap aa;
        aa.loadFromData(buffer,0,Qt::AutoColor);
        QTextCodec*gb2312=QTextCodec::codecForName("GB2312");
        QString str = gb2312->toUnicode(picBuffer->stPlateInfo.as8PlateNum);
        emit carNumberRecEnd(str,&aa);
        this->packHeader_long.clear();
    }
    else if(this->picBuffer_long.length() > (int)(pack->data.u32Size - 32))
    {
        this->packHeader_long.clear();
    }
}

void camera::CameraRecive()
{
    qDebug()<<"*****camera::CameraRecive()*****";
    longsocket_in(this->camerarIp);
}
